<script setup>
import Document from './components/document.vue'
import BreadCrumb from '@/views/note/components/BreadCrumb.vue'
import MoreOperation from './components/MoreOperation.vue'
import { ref, watch, provide, watchEffect } from 'vue'
import {
  httpUpdateNote,
  httpGetNoteDetail,
  httpCreateNoteRelation,
  httpDeleteNoteRelation,
} from '@/api/note'
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import useNoteStore from '@/stores/note'
import NoteLock from './components/NoteLock.vue'
import { flatTree } from '@/utils/tools.ts'
import { storeToRefs } from 'pinia'

const noteState = useNoteStore()
const { noteData } = storeToRefs(noteState)

const route = useRoute()
// const id = route.params.docId
const loading = ref(true)
const title = ref('')
const noteDetail = ref({})
const noteTitle = ref('')
const content = ref('')
const breadcrumbList = ref([])
const editId = ref()
const isLock = ref(false)
const associations = ref([])
const labels = ref([])
const handleUnlock = (value) => {
  isLock.value = false
  if (value === 'remove') {
    initLock.value = false
  }
}
const initLock = ref(false)
const searchParent = (arr, id) => {
  let breadCrumbs = []
  let obj = arr.find((item) => {
    return item.id == id
  })
  if (obj) {
    breadCrumbs.push(obj)
    breadCrumbs = breadCrumbs.concat(searchParent(arr, obj.pid))
  }
  return breadCrumbs
}
watchEffect(() => {
  let cloneArr = JSON.parse(JSON.stringify(noteData.value))
  let flatArr = flatTree(cloneArr)
  const searchArr = searchParent(flatArr, route.params.docId)
  breadcrumbList.value = searchArr.reverse()
  if (breadcrumbList.value.length) {
    noteTitle.value =
      breadcrumbList.value[breadcrumbList.value.length - 1].label
    title.value = breadcrumbList.value[breadcrumbList.value.length - 1].label
  }
})

const updateNote = () => {
  getNoteDetail()
}
const updateBreadcrumb = async () => {
  const res = await httpGetNoteDetail({
    fd_id: route.params.docId,
  })
  const { list } = res
  if (list.length) {
    // const { crumb } = list[0]
    // let arr = crumb.reverse()
    // arr[0] && arr[0].parent_id === 0 && (arr[0].name = '全部笔记')
    // breadcrumbList.value = arr
    noteDetail.value = list[0]
  }
}
provide('updateBreadcrumb', updateBreadcrumb)
const getNoteDetail = async () => {
  loading.value = true
  const res = await httpGetNoteDetail({
    fd_id: route.params.docId,
  })
  const { list } = res
  if (list.length) {
    const firstItem = list[0]
    const { is_lockbox, crumb } = firstItem
    noteDetail.value = firstItem
    // noteTitle.value = firstItem.title
    // title.value = firstItem.title
    content.value = firstItem.content
    editId.value = firstItem.id
    isLock.value = !!is_lockbox
    initLock.value = !!is_lockbox
    // let arr = crumb.reverse()
    labels.value = firstItem.label?.map((x) => x.label_id)
    // arr[0] && arr[0].parent_id === 0 && (arr[0].name = '全部笔记')
    // breadcrumbList.value = arr
    associations.value = getContentAssociations(firstItem.content)
  }
  loading.value = false
}
watch(
  () => route.params.docId,
  () => {
    getNoteDetail()
  },
  {
    immediate: true,
  },
)

const getContentAssociations = (content) => {
  // 正则表达式匹配<a>标签中的href属性
  const regex = /<a[^>]*href="([^"]*)"[^>]*>/g
  // 匹配所有符合条件的链接
  const ids = []
  let match
  const includes = ['/file/doc/', '/file/mindmap/', '/file/drawio/']
  while ((match = regex.exec(content)) !== null) {
    let str = match[1]
    if (str) {
      includes.forEach((include) => {
        if (str.includes(include)) {
          str = str.endsWith('/') ? str.substring(0, str.length - 1) : str
          const id = parseInt(str.split(include)[1].split('?')[0])
          if (!isNaN(id) && id > 0) {
            ids.push(id)
          }
        }
      })
    }
  }
  return ids
}

const handleSave = async (value) => {
  let data = {
    fd_id: editId.value,
    content: value,
    label_id_list: labels.value,
    title: title.value.trim() ? title.value : noteDetail.value.title,
  }
  const res = await httpUpdateNote(data).catch(() => null)
  if (res) {
    if (data.title !== noteTitle.value) {
      noteTitle.value = data.title
      await noteState.getFolderListData()
    }
    // await getNoteDetail(route.params.docId)
    content.value = value
    updateAssociations(value)
  } else {
    ElMessage.error('更新失败')
  }
}

const updateAssociations = (result) => {
  const arr = getContentAssociations(result)
  if (arr.sort().join() !== associations.value.sort().join()) {
    arr.forEach((id1) => {
      if (associations.value.indexOf(id1) < 0) {
        httpCreateNoteRelation({
          source_id: route.params.docId,
          target_id: id1,
        }).catch(() => null)
      }
    })
    associations.value.forEach((id2) => {
      if (arr.indexOf(id2) < 0) {
        httpDeleteNoteRelation({
          source_id: route.params.docId,
          target_id: id2,
        }).catch(() => null)
      }
    })
    associations.value = arr
  }
}
</script>

<template>
  <div class="doc-layout" v-loading="loading">
    <template v-if="!isLock && !loading">
      <div class="header">
        <BreadCrumb :breadcrumbList="breadcrumbList"> </BreadCrumb>
        <MoreOperation
          :data="noteDetail"
          :lock="isLock"
          :initLock="initLock"
          @update="updateNote"
        />
      </div>
      <div class="document">
        <Document
          v-model:title="title"
          @onSave="handleSave"
          :initTitle="noteDetail.title"
          :content="content"
        />
      </div>
    </template>
    <NoteLock
      v-else-if="!loading && isLock"
      :data="noteDetail"
      @unlock="handleUnlock"
      @update="updateNote"
    ></NoteLock>
  </div>
</template>

<style scoped lang="scss">
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 50px;
}

.doc-layout {
  height: 100%;
  .document {
    height: calc(100% - 50px);
  }
}
</style>
